#include "Camera.h"


CCamera::CCamera(void)
: fPI(3.141593f) 
, fYaw(0)
, fPitch(0)
, fZoom(45.0f)
, fMoveSpeed(0.1f)
, fRotateSpeed(0.017f)
, fZoomSpeed(0.1f)
{
}


CCamera::~CCamera(void)
{
}

void CCamera::SetValue(GLfloat eyex, GLfloat eyey, GLfloat eyez,
		GLfloat centerx, GLfloat centery, GLfloat centerz)
{
	vecEyePosition = glm::vec3(eyex, eyey, eyez);

	glm::vec3 vecDirect = glm::vec3(centerx, centery, centerz) - vecEyePosition;
	vecDirection = vecDirect;

	float len = (float)length(vecDirect);
	fPitch = asin(vecDirect.y / len);

	vecDirect.y = 0;
	len = (float)length(vecDirect);
	fYaw = asin(-vecDirect.z / len);
	if (vecDirect.x < 0)
	{
		fYaw = 3.141593f - fYaw;
	}
}

glm::mat4 CCamera::GetViewMatrix(void)
{
	return glm::lookAt(vecEyePosition, vecEyePosition + vecDirection, glm::vec3(0.0f, 1.0f, 0.0f));
}

void CCamera::MoveForward(int step)
{
	glm::vec3 vecDirect = vecDirection;
	vecDirect.y = 0;

	glm::normalize(vecDirect);

	vecEyePosition += (GLfloat)step * fMoveSpeed * vecDirect;
}

void CCamera::MoveLeft(int step)
{
	glm::vec3 vecUp(0.0f, 1.0f, 0.0f);
	glm::vec3 vecMove = glm::normalize(glm::cross(vecDirection, vecUp));

	vecEyePosition += (GLfloat)step * fMoveSpeed * vecMove;
}

void CCamera::YawAndPitch(int dx, int dy)
{
	fPitch -= (float)dy * fRotateSpeed;
	if( fPitch > fPI / 2.0f )
	{
		fPitch = fPI / 2.0f;
	}
	if( fPitch < -fPI / 2.0f )
	{
		fPitch = -fPI / 2.0f;
	}

	fYaw -= (float)dx * fRotateSpeed;
	if( fYaw > 2 * fPI || fYaw < -2 * fPI )
	{
		fYaw = 0.0f;
	}

	float len = (float)length(vecDirection);
	glm::vec3 vecCenterTarget = glm::vec3(vecEyePosition.x + len * cos(fPitch) * cos(fYaw),
		vecEyePosition.y + len * sin(fPitch),
		vecEyePosition.z - len * cos(fPitch) * sin(fYaw));

	vecDirection = vecCenterTarget - vecEyePosition;
}

void CCamera::Zoom(int step)
{
	fZoom += (float)step * fZoomSpeed;

	if (fZoom > 89.0f)
	{
		fZoom = 89.0f;
	}
	else if (fZoom < 1.0f)
	{
		fZoom = 1.0f;
	}
}

GLfloat CCamera::GetZoom(void)
{
	return fZoom;
}